package com.aube.tinker;

import android.content.Context;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.FileRequest;
import com.huyn.baseframework.net.BFJSONRequest;
import com.huyn.baseframework.net.HttpRequestLoader;
import com.huyn.baseframework.net.OpenApi;
import com.huyn.baseframework.utils.Constant;
import com.huyn.baseframework.utils.FileMD5Verify;
import com.huyn.baseframework.utils.SharedPrefUtil;
import com.huyn.baseframework.utils.StorageUtil;
import com.huyn.baseframework.utils.StringUtils;
import com.huyn.baseframework.utils.Utils;
import com.tencent.tinker.lib.tinker.TinkerInstaller;

import java.io.File;
import java.util.HashMap;

/**
 * Created by huyaonan on 16/11/21.
 */
public class TinkerPatchManager {

    public static final String TRUE_VERSION = "TRUE_VERSION";
    public static String targetVersion = "";
    private static TinkerPatchManager mInstance;
    private Context mContext;

    private TinkerPatchManager(Context context) {
        this.mContext = context;
    }

    public static synchronized TinkerPatchManager getInstance(Context context) {
        if(mInstance == null)
            mInstance = new TinkerPatchManager(context);
        return mInstance;
    }

    public void getPatch() {
        Utils.Log("TINKERPATCH", "start get patch");
        HashMap<String, String> parameterMap = new HashMap<>();
        parameterMap.put(OpenApi.API_METHOD, OpenApi.GET_HOTFIX);
        final BFJSONRequest rq = new BFJSONRequest(TinkerPatchModel.class, parameterMap, new Response.Listener<TinkerPatchModel>() {

            @Override
            public void onResponse(TinkerPatchModel response) {
                if(response != null && response.success())
                    downloadPatch(response.data);
            }

            @Override
            public void onErrorResponse(VolleyError error) {
            }

            @Override
            public void onStart() {
            }
        });
        HttpRequestLoader.getInstance(mContext).startCacheLoader("", rq, true);
    }

    private void downloadPatch(final TinkerPatch patch) {
        Utils.Log("TINKERPATCH", "start download patch");
        if(patch == null || !isValidPatch(patch))
            return;

        FileRequest request = new FileRequest(patch.download, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                if(StringUtils.isNotBlank(response)) {
                    try {
                        boolean verifyResult = FileMD5Verify.md5sum(new File(response), patch.md5);
                        Utils.Log("TINKERPATCH", "download patch over");
                        if(verifyResult) {
                            Utils.Log("TINKERPATCH", "verify success");
                            targetVersion = patch.targetVersion;
                            TinkerInstaller.onReceiveUpgradePatch(mContext.getApplicationContext(), response);
                        } else
                            new File(response).delete();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onErrorResponse(VolleyError error) {

            }

            @Override
            public void onStart() {

            }
        }, null);

        String pkgName = (mContext.getPackageName() + "_" + patch.appVersion).replace(".", "_");
        request.setFileTitle(pkgName);
        request.setCanUseSDCard(StorageUtil.checkSDWritePermission(mContext));
        HttpRequestLoader.getInstance(mContext).startHttpLoader(request);
    }

    private boolean isValidPatch(TinkerPatch patch) {
        Utils.Log("TINKERPATCH", "start verify patch");
        if(StringUtils.isBlank(patch.download) || StringUtils.isBlank(patch.appVersion) || StringUtils.isBlank(patch.md5))
            return false;
        String trueVersion = Constant.APP_VERSION;
        //本地version比服务器version大,直接忽略
        int state = trueVersion.compareTo(patch.appVersion);
        Utils.Log("TINKERPATCH", "trueVersion:" + trueVersion + "/" + state);
        if (state != 0)
            return false;
        state = Constant.APP_TRUE_VERSION.compareTo(patch.targetVersion);
        if(state >= 0)
            return false;
        Utils.Log("TINKERPATCH", "start to fetch patch");
        return true;
    }

    public void saveTinkerVersion() {
        if(StringUtils.isNotBlank(targetVersion)) {
            SharedPrefUtil.getInstance(mContext).putString(TRUE_VERSION, targetVersion);
            targetVersion = "";
        }
    }

}
